package com.geralt.im.client;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;

import javax.swing.JOptionPane;

import com.geralt.im.controller.Controller;
import com.geralt.im.jsonparser.impl.ResponseJsonParser;
import com.geralt.im.protocol.Response;
import com.geralt.im.tool.JsonTool;

public class JsonClientThread extends ClientReaderRunnable{

	InputStream is = null;
	BufferedReader ois = null;
	BufferedWriter oos = null;
	OutputStream os = null;
	private static JsonClientThread instance;

	private JsonClientThread(Socket socket) {
		super(socket);
		
		try {
			os = socket.getOutputStream();
			oos = new BufferedWriter(new OutputStreamWriter(os));
			is = socket.getInputStream();
			ois = new BufferedReader(new InputStreamReader(is));
		} catch (IOException e) {
			// closeSocket();
			e.printStackTrace();
		}
	}

	public void run() {

		try {
			while (IMClient.flag) {
				read();
			}
		} catch (Exception e) {
			JOptionPane.showMessageDialog(null, "Can't connect to Server");
			closeSocket();
		}
		if (is != null) {
			closeSocket();
		}
	}

	public void write(Object request) {
		try {
			JsonTool jt = JsonTool.getInstance();
			String writeString = jt.objectToString(request);
			System.out.println("Socket is closed:"+socket.isClosed());
			oos.write(writeString+"\n");
			oos.flush();
			System.out.println(writeString);
		} catch (IOException e) {
			JOptionPane.showMessageDialog(null, "Can't connect to Server");
			closeSocket();
		}
	}

	public Response read() throws ClassNotFoundException, IOException {
		String jsonString = (String) ois.readLine();
		if(jsonString==null){
			return null;
		}
		System.out.println("read String"+jsonString);			/////////////////////////////
		ResponseJsonParser parser = new ResponseJsonParser();
		Response rs = (Response) parser.parse(jsonString);
		Controller.getInstance().excute(rs);
		
		return rs;
	}

	public void closeSocket() {
		try {
			is.close();
			ois.close();
			if (os != null) {
				os.close();
				oos.close();
			}
			socket.close();
		} catch (IOException e) {
			// e.printStackTrace();
			JOptionPane.showMessageDialog(null, "Can't connect to Server");
		}
	}

	public synchronized static JsonClientThread getInstance(Socket socket) {
		if (instance == null) {
			instance = new JsonClientThread(socket);
		}
		return instance;
	}
	
}
